<!DOCTYPE html>
<html lang="en"><head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1"><!-- Begin Jekyll SEO tag v2.8.0 -->
<title>0016: Scroll Wheel and More Button Stuff | gtkDcoding</title>
<meta name="generator" content="Jekyll v4.3.4" />
<meta property="og:title" content="0016: Scroll Wheel and More Button Stuff" />
<meta name="author" content="Ron Tarrant" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="Getting feedback from the mouse’s scrollwheel in GTK - a D language tutorial." />
<meta property="og:description" content="Getting feedback from the mouse’s scrollwheel in GTK - a D language tutorial." />
<link rel="canonical" href="http://localhost:4000/posts/0016-scroll-pointer-all.html" />
<meta property="og:url" content="http://localhost:4000/posts/0016-scroll-pointer-all.html" />
<meta property="og:site_name" content="gtkDcoding" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2019-03-08T00:00:00-05:00" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="0016: Scroll Wheel and More Button Stuff" />
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"Ron Tarrant"},"dateModified":"2019-03-08T00:00:00-05:00","datePublished":"2019-03-08T00:00:00-05:00","description":"Getting feedback from the mouse’s scrollwheel in GTK - a D language tutorial.","headline":"0016: Scroll Wheel and More Button Stuff","mainEntityOfPage":{"@type":"WebPage","@id":"http://localhost:4000/posts/0016-scroll-pointer-all.html"},"url":"http://localhost:4000/posts/0016-scroll-pointer-all.html"}</script>
<!-- End Jekyll SEO tag -->
<link rel="stylesheet" href="../assets/main.css">
  <link rel="stylesheet" href="../css/style.css" /><link type="application/atom+xml" rel="alternate" href="http://localhost:4000/feed.xml" title="gtkDcoding" /></head>
<body><header class="site-header" role="banner">

  <div class="wrapper"><a class="site-title" rel="author" href="../">gtkDcoding</a><nav class="site-nav">
        <input type="checkbox" id="nav-trigger" class="nav-trigger" />
        <label for="nav-trigger">
          <span class="menu-icon">
            <svg viewBox="0 0 18 15" width="18px" height="15px">
              <path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
            </svg>
          </span>
        </label>

        <div class="trigger"><a class="page-link" href="../about.html">About</a><a class="page-link" href="../index-reverse.html">Posts in Date Order</a><a class="page-link" href="../topics.html">Blog Posts by Topic</a></div>
      </nav></div>
</header>
<main class="page-content" aria-label="Content">
      <div class="wrapper">
        <article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
	<header class="post-header">
		<link rel="stylesheet" href="../css/font_size.css" />
		<link rel="stylesheet" href="../css/figure.css" />
		<link rel="stylesheet" href="../css/topics/mouse.css" />  <!-- sub in the tag/topic -->
		<link rel="stylesheet" href="../css/modal.css" />
		<link rel="stylesheet" href="../css/post.css" />
		<link rel="stylesheet" href="../css/mascot_effects.css" />

		
		
		<p class="post-meta">
		<time class="dt-published" datetime="2019-03-08T00:00:00-05:00" itemprop="datePublished">Friday, March 8, 2019
		</time>• by <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span class="p-author h-card" itemprop="name">Ron Tarrant</span></span></p>
	</header>

	<div class="post-content e-content" itemprop="articleBody">
		<div class="skew-line"></div>
		<h1 id="0016-scroll-wheel-and-more-button-stuff">0016: Scroll-wheel and More Button Stuff</h1>

<h2 id="tracking-the-scroll-wheel">Tracking the Scroll-wheel</h2>

<div class="screenshot-frame">
	<div class="frame-header">
		Results of this example:
	</div>
	<div class="frame-screenshot">
		<figure>
			<img id="img0" src="../images/screenshots/005_mouse/mouse_05.png" alt="Current example output" />		<!-- img# -->
			
			<!-- Modal for screenshot -->
			<div id="modal0" class="modal">																	<!-- modal# -->
				<span class="close0">&times;</span>															<!-- close# -->
				<img class="modal-content" id="img00" />															<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal0");														// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img0");															// img#
			var modalImg = document.getElementById("img00");													// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close0")[0];											// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>
			<figcaption>
			Current example output
			</figcaption>
		</figure>
	</div>

	<div class="frame-terminal">
		<figure class="right">
			<img id="img1" src="../images/screenshots/005_mouse/mouse_05_term.png" alt="Current example terminal output" />		<!-- img#, filename -->

			<!-- Modal for terminal shot -->
			<div id="modal1" class="modal">																				<!-- modal# -->
				<span class="close1">&times;</span>																		<!-- close# -->
				<img class="modal-content" id="img11" />																		<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal1");																	// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img1");																		// img#
			var modalImg = document.getElementById("img11");																// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close1")[0];														// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>

			<figcaption>
				Current example terminal output (click for enlarged view)
			</figcaption>
		</figure>
	</div>

	<div class="frame-footer">																								<!-- ------------- filename (below) --------- -->
		The code file for this example is available <a href="https://github.com/rontarrant/gtkd_demos/blob/master/005_mouse/mouse_05_scroll_wheel.d" target="_blank">here</a>.
	</div>
</div>

<p>Time to get down to the nitty gritty of harnessing the mouse wheel.</p>

<p>Got a 3D object you need to zoom in on? How about lines and lines of text that need to be scrolled through? Yeah, that’s what we’re laying groundwork for today. Here’s the constructor:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">this</span><span class="p">()</span>
<span class="p">{</span>
	<span class="k">super</span><span class="p">(</span><span class="n">title</span><span class="p">);</span>
	<span class="n">addOnDestroy</span><span class="p">(</span><span class="k">delegate</span> <span class="kt">void</span><span class="p">(</span><span class="n">Widget</span> <span class="n">w</span><span class="p">)</span> <span class="p">{</span> <span class="n">quitApp</span><span class="p">();</span> <span class="p">}</span> <span class="p">);</span>
	
	<span class="c1">// make the window sensitive to mouse wheel scrolling</span>
	<span class="n">addOnScroll</span><span class="p">(&amp;</span><span class="n">onScroll</span><span class="p">);</span>
	
	<span class="c1">// Show the window and its contents...</span>
	<span class="n">showAll</span><span class="p">();</span>
	
<span class="p">}</span> <span class="c1">// this()</span>
</code></pre></div></div>

<p>This should be pretty familiar by now, hook up a signal to a callback using one of the <code class="language-plaintext highlighter-rouge">addOnXxxxx()</code> functions, in this case <code class="language-plaintext highlighter-rouge">addOnScroll()</code> and here’s the callback:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="kt">bool</span> <span class="n">onScroll</span><span class="p">(</span><span class="n">Event</span> <span class="n">event</span><span class="p">,</span> <span class="n">Widget</span> <span class="n">widget</span><span class="p">)</span>
<span class="p">{</span>
	<span class="kt">bool</span> <span class="n">value</span> <span class="p">=</span> <span class="kc">false</span><span class="p">;</span> <span class="c1">// assume no scrolling</span>
	
	<span class="k">if</span><span class="p">(</span><span class="n">event</span><span class="p">.</span><span class="n">scroll</span><span class="p">.</span><span class="n">direction</span> <span class="p">==</span> <span class="n">ScrollDirection</span><span class="p">.</span><span class="n">DOWN</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">value</span> <span class="p">=</span> <span class="kc">true</span><span class="p">;</span>
		<span class="n">writeln</span><span class="p">(</span><span class="s">"scrolling down..."</span><span class="p">);</span>
	<span class="p">}</span>
	<span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">event</span><span class="p">.</span><span class="n">scroll</span><span class="p">.</span><span class="n">direction</span> <span class="p">==</span> <span class="n">ScrollDirection</span><span class="p">.</span><span class="n">UP</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">value</span> <span class="p">=</span> <span class="kc">true</span><span class="p">;</span>
		<span class="n">writeln</span><span class="p">(</span><span class="s">"scrolling up..."</span><span class="p">);</span>
	<span class="p">}</span>

	<span class="k">return</span><span class="p">(</span><span class="n">value</span><span class="p">);</span>

<span class="p">}</span> <span class="c1">// onScroll()</span>
</code></pre></div></div>

<p>Again, we have to dig a bit to find the data we want: the direction the mouse wheel is turning. The <code class="language-plaintext highlighter-rouge">ScrollDirection</code> <em>enum</em> in <code class="language-plaintext highlighter-rouge">gtk.c.types</code> (that’s <em>generated/gtkd/gtk/c/types.d</em> if you want to see for yourself) provides us with <code class="language-plaintext highlighter-rouge">UP</code> and <code class="language-plaintext highlighter-rouge">DOWN</code> so we can check. Makes it easy. I’ve added in a bit of return value roughage so we know for sure we’re done with any signal chain that might end up being processed at the same time.</p>

<h2 id="left-middle--right-mouse-buttons">Left, Middle, &amp; Right Mouse Buttons</h2>

<div class="screenshot-frame">
	<div class="frame-header">
		Results of this example:
	</div>
	<div class="frame-screenshot">
		<figure>
			<img id="img2" src="../images/screenshots/005_mouse/mouse_06.png" alt="Current example output" />		<!-- img# -->
			
			<!-- Modal for screenshot -->
			<div id="modal2" class="modal">																<!-- modal# -->
				<span class="close2">&times;</span>														<!-- close# -->
				<img class="modal-content" id="img22" />														<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal2");													// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img2");														// img#
			var modalImg = document.getElementById("img22");												// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close2")[0];										// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>
			<figcaption>
			Current example output
			</figcaption>
		</figure>
	</div>

	<div class="frame-terminal">
		<figure class="right">
			<img id="img3" src="../images/screenshots/005_mouse/mouse_06_term.png" alt="Current example terminal output" /> 		<!-- img#, filename -->

			<!-- Modal for terminal shot -->
			<div id="modal3" class="modal">																			<!-- modal# -->
				<span class="close3">&times;</span>																	<!-- close# -->
				<img class="modal-content" id="img33" />																	<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal3");																// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img3");																	// img#
			var modalImg = document.getElementById("img33");															// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close3")[0];													// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>

			<figcaption>
				Current example terminal output (click for enlarged view)
			</figcaption>
		</figure>
	</div>

	<div class="frame-footer">																							<!--------- filename (below) ------------>
		The code file for this example is available <a href="https://github.com/rontarrant/gtkd_demos/blob/master/005_mouse/mouse_06_left_middle_right.d" target="_blank">here</a>.
	</div>
</div>

<p>Let’s throw caution to the wind and put a <code class="language-plaintext highlighter-rouge">Button</code> back in the window, just one, and give it something interesting to do…</p>

<p>When I was writing out these examples, I’d forgotten I’d already talked about differentiating between mouse buttons, so I wrote this one. This one, though, does process things in a different way:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="kt">bool</span> <span class="n">onButtonRelease</span><span class="p">(</span><span class="n">Event</span> <span class="n">event</span><span class="p">,</span> <span class="n">Widget</span> <span class="n">widget</span><span class="p">)</span>
<span class="p">{</span>
	<span class="kt">bool</span> <span class="n">value</span> <span class="p">=</span> <span class="kc">false</span><span class="p">;</span>
	
	<span class="k">if</span><span class="p">(</span><span class="n">event</span><span class="p">.</span><span class="n">type</span> <span class="p">==</span> <span class="n">EventType</span><span class="p">.</span><span class="n">BUTTON_RELEASE</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">GdkEventButton</span><span class="p">*</span> <span class="n">buttonEvent</span> <span class="p">=</span> <span class="n">event</span><span class="p">.</span><span class="n">button</span><span class="p">;</span>

		<span class="n">mouseRelease</span><span class="p">(</span><span class="n">buttonEvent</span><span class="p">.</span><span class="n">button</span><span class="p">);</span>

		<span class="n">value</span> <span class="p">=</span> <span class="kc">true</span><span class="p">;</span>
	<span class="p">}</span>

	<span class="k">return</span><span class="p">(</span><span class="n">value</span><span class="p">);</span>
	
<span class="p">}</span> <span class="c1">// onButtonRelease()</span>
</code></pre></div></div>

<p>From here, you could look at the button data, a <em>uint</em>, to see which button was pressed. We handle this with the <code class="language-plaintext highlighter-rouge">mouseRelease()</code> function:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="n">mouseRelease</span><span class="p">(</span><span class="kt">uint</span> <span class="n">mouseButton</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">writeln</span><span class="p">(</span><span class="s">"The "</span><span class="p">,</span> <span class="n">mouseButtons</span><span class="p">[</span><span class="n">mouseButton</span><span class="p">],</span> <span class="s">" was released."</span><span class="p">);</span>
	
<span class="p">}</span> <span class="c1">// mouseRelease()</span>
</code></pre></div></div>

<p>Which translates the <em>uint</em> to plain English using the <code class="language-plaintext highlighter-rouge">mouseButtons</code> array defined at the top of the <code class="language-plaintext highlighter-rouge">MyLMRButton</code> class:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">string</span><span class="p">[]</span> <span class="n">mouseButtons</span> <span class="p">=</span> <span class="p">[</span><span class="s">"None"</span><span class="p">,</span> <span class="s">"Left"</span><span class="p">,</span> <span class="s">"Middle"</span><span class="p">,</span> <span class="s">"Right"</span><span class="p">];</span>
</code></pre></div></div>

<p>You may wonder why there’s a <code class="language-plaintext highlighter-rouge">“None”</code> element in this array, but it’s there because there is no mouse button #0. It keeps us from having to subtract ‘1’ each time to find our way to the correct array element.</p>

<p>And so we come to the end of another blog post. Be kind to each other and we’ll talk again soon.</p>

<div class="blog-nav">
	<div style="float: left;">
		<a href="./0015-enter-leave.html">Previous: Entering and Leaving</a>
	</div>
	<div style="float: right;">
		<a href="./0017-change-pointer.html">Next: Mouse Pointer</a>
	</div>
</div>
<p>
	<h3></h3>
<div class="inpage-frame">
	<a href="https://github.com/sponsors/rontarrant">
		<BR>
		<BR>
		<B>Is this article useful? Educational? Entertaining, perhaps?</B>
		<BR>
		<figure class="left">
			<img src="../images/favorite_32.png" alt="Sponsorship heart" style="width: 32px; height: 32px;">
		</figure>
		You're free to accept or decline this invitation to become our newest sponsor.
	</a>
</div>
	<h4 class="comment-blurb"><B>Comments? Questions? Observations?</B></h4>
	<p>
		Did we miss a tidbit of information that would make this post even more informative? Let's talk about it in the comments.
	</p>
	<script src="https://utteranc.es/client.js"
		repo="rontarrant"
		issue-term="pathname"
		theme="github-light"
		crossorigin="anonymous"
		async>
	</script>
	<ul>
		<li> come on over to the <a href="https://forum.dlang.org/">D Language Forum</a> and look for one of the <i>gtkDcoding</i> announcement posts, </li>
		<li> drop by <a href="https://forum.gtkd.org/">the <i>GtkD Forum</i></a>,</li>
		<li> follow the link below to email me, or</li>
		<li> go to the	<a href="https://www.facebook.com">gtkDcoding Facebook page.</a></li>
	</ul>
</p>
<p> You can also subscribe <a href="/feed.xml">via RSS</a> so you won't miss anything. Thank you very much for dropping by.</p>
<p>&copy; Copyright 2025 Ron Tarrant </p>
</div>

	<a class="u-url" href="./0016-scroll-pointer-all.html" hidden></a>
</article>

      </div>
    </main><footer class="site-footer h-card">
  <data class="u-url" href="/"></data>

  <div class="wrapper">

    <h2 class="footer-heading">gtkDcoding</h2>

    <div class="footer-col-wrapper">
      <div class="footer-col footer-col-1">
        <ul class="contact-list">
          <li class="p-name">Ron Tarrant</li><li><a class="u-email" href="mailto:gtkDcoding@gmail.com">gtkDcoding@gmail.com</a></li></ul>
      </div>

      <div class="footer-col footer-col-2"><ul class="social-media-list"><li><a href="https://github.com/rontarrant"><svg class="svg-icon"><use xlink:href="../assets/minima-social-icons.svg#github"></use></svg> <span class="username">rontarrant</span></a></li></ul>
</div>

      <div class="footer-col footer-col-3">
        <p>Simple examples of how to use GtkD to build GUI applications.</p>
      </div>
    </div>

  </div>

</footer>
</body>

</html>
